/// <reference path="./../Main.ts" />
namespace apeng {

	const _date = new Date()


	/**
	 * 时间处理类
	 *
	 * @export
	 * @class Times
	 */
	export class Times {

		public static texts = {
			10001: "年",
			10002: "月",
			10003: "日",
			10004: "小时",
			10005: "时",
			10006: "分",
			10007: "秒",
		}


		/**一天的总时间 毫秒 */
		public static dayOnce = 24 * 60 * 60 * 1000

		/**获取当前时间戳 外面赋值*/
		public static get now() {
			return Date.now()
		}

		public static getDayOfYear(time: number) {
			_date.setTime(time)
			const currentYear = _date.getFullYear().toString()
			// 今天减今年的第一天（xxxx年01月01日）
			const hasTimestamp = time - new Date(currentYear).getTime()
			// 86400000 = 24 * 60 * 60 * 1000
			const hasDays = Math.ceil(hasTimestamp / 86400000) + 1
			// 结果：今天是2018年的第329天
			return hasDays
		}

		/**
		 * 格式化时间
		 * 2012/2/3 00:22:33
		 * @param now 
		 * @returns 
		 */
		public static toLocaleString(now?: number, hour = true, interval = " "): string {
			if (!now)
				now = Times.now
			_date.setTime(now)
			return _date.getFullYear() + "/" + (_date.getMonth() + 1) + "/" + _date.getDate() + (hour ? (interval + this.numHour(now, true)) : "")
		}

		/**
		 * 格式化时间
		 * 2012年2月3日 00:22:33
		 * @param now 
		 * @returns 
		 */
		public static toLocaleStringChina(now?: number): string {
			if (!now)
				now = Times.now
			_date.setTime(now)
			return _date.getFullYear() + Times.texts[10001] + (_date.getMonth() + 1) + Times.texts[10002] + _date.getDate() + Times.texts[10003] + " " + this.numHour(now, true)
		}

		public static getMonthOfYear(now?: number) {
			if (!now)
				now = Times.now
			_date.setTime(now)
			return _date.getMonth() + 1
		}

		public static getDayOfMonth(now?: number) {
			if (!now)
				now = Times.now
			_date.setTime(now)
			return _date.getDate()
		}

		private static _console = {}

		public static console(key: string) {
			(Times._console as any)[key] = Times.now as any
		}

		public static consoleEnd(key: string, ...args: any[]) {
			console.log(key, (Times.now - ((Times._console as any)[key] || Times.now)) / 1000, ...args)
		}

		public static get Date(): {
			/**获取年 */
			getFullYear(): number;
			/**月 */
			getMonth(): number;
			/**一月的第几天 */
			getDate(): number;
			/**一周的第几天 */
			getDay(): number;
			/**时 */
			getHours(): number;
			/**分 */
			getMinutes(): number;
			/**秒 */
			getSeconds(): number;
			/**获取本地时间 2017-01-10 22:52:37 */
			toLocaleString(): string;
			/**22:52:37 */
			toLocaleTimeString(): string;
			/**22:52:37 GMT+0800 (中国标准时间) */
			toTimeString(): string;
			setTime(time: number): number;
		} {
			let date2 = new Date()
			date2.setTime(Times.now)
			return date2
		}

		/**获取本月一共有多少天 */
		public static getMontyByDay() {
			let date = Times.Date;
			let year = date.getFullYear();
			let monty = date.getMonth() + 1;
			return new Date(year, monty, 0).getDate();
		}


		/**转换时间戳 utc 天 */
		public static day(time?: number): number {
			return Math.floor((Times.hour(time) + 8) / 24)
		}

		/**转换时间戳 时 */
		public static hour(time?: number): number {
			return Math.floor(Times.minute(time) / 60)
		}

		/**转换时间戳 分 */
		public static minute(time?: number): number {
			return Math.floor(Times.second(time) / 60)
		}

		// 同帧大量调用 使用缓存
		public static _secondCache = Times.now

		/**转换时间戳 秒 */
		public static second(time?: number): number {
			if (time == null || time == undefined) {
				// if (_timer.dirtyMark("Times.second")) {
				if (true) {
					time = Times.now
					Times._secondCache = Math.floor(time / 1000)
				}
			}
			else
				return Math.floor(time / 1000)

			return Times._secondCache
		}

		/**
		 * 格式化时间戳 utc时间 数字显示
		 * @param time 
		 * @param hour 当小于 1小时时，显示 00:59:12 反之 59:12
		 * @returns 00:00:00
		 */
		public static numHour(time?: number, hour: boolean = false) {

			let res: string = Times.converMinTen(Times.second(time) % 60) + ""

			if (Times.second(time) >= 60)
				res = Times.converMinTen(Times.minute(time) % 60) + ":" + res
			else
				res = "00:" + res


			if (Times.minute(time) >= 60)
				res = Times.converMinTen((Times.hour(time) + 8) % 24) + ":" + res
			else {
				if (hour)
					res = "00:" + res
			}
			return res
		}

		/**一天中的第几小时 */
		public static dayByHour(time?: number) {
			return (Times.hour(time) + 8) % 24
		}

		/**
		 * 格式化时间戳 数字显示(无转换)适用于倒计时
		 * @param time 
		 * @returns 00:00:00
		 */
		public static numHourCountDown(time?: number, hour: boolean = false) {
			if (time && time <= 0) {
				if (hour)
					return "00:00:00"
				else
					return "00:00"
			}

			let res: string = Times.converMinTen(Times.second(time) % 60) + ""

			if (Times.second(time) >= 60)
				res = Times.converMinTen(Times.minute(time) % 60) + ":" + res
			else
				res = "00:" + res

			if (Times.minute(time) >= 60)
				res = Times.converMinTen(Times.hour(time)) + ":" + res
			else {
				if (hour)
					res = "00:" + res
			}
			return res
		}


		/**
		 * 格式化时间戳 中文显示(无转换)适用于倒计时
		 * @param time 
		 * @returns 1小时10分3秒
		 */
		public static chinaHourCountDown(time?: number, hour: boolean = false) {
			if (time && time <= 0) {
				if (hour)
					return "0" + Times.texts[10004] + "0" + Times.texts[10006] + "0" + Times.texts[10007]
				else
					return "0" + Times.texts[10006] + "0" + Times.texts[10007]
			}

			let res: string = Times.converMinTen(Times.second(time) % 60) + Times.texts[10007]

			if (Times.second(time) >= 60)
				res = Times.converMinTen(Times.minute(time) % 60) + Times.texts[10006] + res
			else
				res = "0分" + res

			if (Times.minute(time) >= 60)
				res = Times.converMinTen(Times.hour(time)) + Times.texts[10004] + res
			else {
				if (hour)
					res = "0" + Times.texts[10004] + res
			}
			return res
		}


		/**格式化时间戳 数字显示 @requires 00:00 */
		public static numMinute(time?: number): string {

			let res = Times.converMinTen(Times.second(time) % 60) + ""

			if (Times.second(time) >= 60)
				res = Times.converMinTen(Times.minute(time)) + ":" + res
			else
				res = "00:" + res


			return res
		}

		/**格式化时间戳 数字显示 @requires 00 */
		public static numSecond(time?: number): string {
			return Times.converMinTen(Times.second(time))
		}

		/** 格式化时间戳 中文显示 @requires 09时02分03秒 */
		public static chinaHour(time?: number): string {
			let res: string
			res = Times.converMinTen(Times.second(time) % 60) + Times.texts[10007]

			if (Times.second(time) >= 60)
				res = Times.converMinTen(Times.minute(time) % 60) + Times.texts[10006] + res

			if (Times.minute(time) >= 60)
				res = Times.converMinTen(Times.hour(time) % 24) + Times.texts[10005] + res
			return res
		}

		/** 格式化时间戳 中文显示 @requires 09时02分*/
		public static numHourAndMinute(time?: number): string {
			let res = Times.converMinTen(Times.minute(time) % 60) + ":00"
			if (Times.minute(time) >= 60)
				res = Times.converMinTen(Times.hour(time) % 24) + ":" + res
			return res
		}

		/** 格式化时间戳 中文显示 @requires 09时02分*/
		public static chinaHourAndMinute(time?: number): string {
			let res: string
			res = Times.converMinTen(Times.minute(time) % 60) + Times.texts[10006]
			if (Times.minute(time) >= 60)
				res = Times.converMinTen(Times.hour(time) % 24) + Times.texts[10005] + res
			return res
		}

		/** 格式化时间戳 中文显示 @requires 02分03秒 */
		public static chinaMinute(time?: number): string {
			let res: string;
			res = Times.converMinTen(Times.second(time) % 60) + Times.texts[10007]

			if (Times.second(time) >= 60)
				res = Times.converMinTen(Times.minute(time) % 60) + Times.texts[10006] + res

			return res
		}

		/** 格式化时间戳 中文显示 @requires 03秒 */
		public static chinaSecond(time?: number): string {
			return Times.converMinTen(Times.second(time)) + Times.texts[10007]
		}

		/**小于10的数字加 0 */
		public static converMinTen(num: number): string {
			return num < 10 ? ("0" + num) : num.toString()
		}

		/**获取当前天已过的时间 utc时间 */
		public static getToDayNow(): number {
			let time = Times.now
			let res: number = (Times.second(time) % 60) * 1000
			if (Times.second(time) >= 60)
				res += (Times.minute(time) % 60) * 60 * 1000
			if (Times.minute(time) >= 60)
				res += ((Times.hour(time) + 8) % 24) * 60 * 60 * 1000
			return res
		}

		/**当前天还剩余的 时间 毫秒 */
		public static getToDayLeave() { return Times.dayOnce - Times.getToDayNow() }


		/**获取时间戳的时间 到现在过了的天数 */
		public static getToNowDay(lastTime: number) {
			return Times.day(Times.now - lastTime)
		}


		/**返回一天中剩余的时间 单位 秒 */
		public static getOneDayLeftTime() {
			let curTime = Times.numHour(Times.now)
			let timeArr = curTime.split(":")
			let passHour = Number(timeArr[0])
			let passMinute = Number(timeArr[1])
			let passSecond = Number(timeArr[2])
			return (23 - passHour) * 60 * 60 + (59 - passMinute) * 60 + (59 - passSecond)
		}

		/**返回 当前周 是一年中的第几周 */
		public static getWeekOfTheYear() {
			_date.setTime(Times.now)
			let curTime = _date
			let firstDay = new Date(curTime.getFullYear(), 0, 1)
			let dayOfWeek = firstDay.getDay()
			let spendDay = 1
			if (dayOfWeek != 0) {
				spendDay = 7 - dayOfWeek + 1
			}
			firstDay = new Date(curTime.getFullYear(), 0, 1 + spendDay)
			let d = Math.ceil((curTime.valueOf() - firstDay.valueOf()) / 86400000)
			let result = Math.ceil(d / 7)
			return result + 1
		}

		/**时间戳是当年的第几天  */
		public static getDayOfTheYear(time: number) {
			_date.setTime(time)
			let curTime = _date
			let firstDay = new Date(curTime.getFullYear(), 0, 1)
			let day = Math.ceil((curTime.valueOf() - firstDay.valueOf()) / (24 * 60 * 60 * 1000))
			return day
		}
		/**类时间戳 */
		private time: number = 0

		/**
		 * 可传入时间戳，默认取当前时间戳
		 * @param {number} [time]
		 * @memberof Times
		 */
		constructor(time?: number) {
			if (time)
				this.time = time;
			else
				this.time = Times.now

		}

		/**
		 * 相加
		 * @param {number} time 毫秒
		 * @memberof Times
		 */
		public add(time: number): Times {
			this.time += time
			return this
		}

		public sub(time: number): Times {
			this.time -= time
			return this
		}

		public get now(): number { return this.time }

		/**转换时间戳 天 */
		public get day(): number { return Math.floor(this.hour / 24) }

		/**转换时间戳 时 */
		public get hour(): number { return Math.floor(this.minute / 60) }

		/**转换时间戳 分 */
		public get minute(): number { return Math.floor(this.second / 60) }

		/**转换时间戳 秒 */
		public get second(): number { return Math.floor(this.time / 1000) }

		public get numHour() { return Times.numHour(this.time) }
		public get numMinute(): string { return Times.numMinute(this.time) }
		public get numSecond(): string { return Times.numSecond(this.time) }
		public get chinaHour(): string { return Times.chinaHour(this.time) }
		public get chinaMinute(): string { return Times.chinaMinute(this.time) }
		public get chinaSecond(): string { return Times.chinaSecond(this.time) }
		public converMinTen(): string { return Times.converMinTen(this.time) }



	}
}